package MTRequest;

import java.util.ArrayList;

import android.database.Cursor;
import MTClient.ClientLogic;
import MTClient.ClientTCPConnection;
import MTClient.MTConstant;
import MTClient.MessageCentre;
import SQLManager.SQLManager;

/**
 * This class handle to synchronize the User's local DB with Server's DB.
 * @author King
 *
 */
public class MTClientSynDataFromLocalDB extends MTRequest{

	private int curIndex = 0;
	ArrayList< Integer > mUpdateItemID = new ArrayList();
	
	public MTClientSynDataFromLocalDB( MessageCentre aMSGCenter )
	{
		super( aMSGCenter );
		this.mRequestState = MTConstant.MT_REQ_CSYN_DFLDB_PREPARE_PRODUCT;
	}
	
	protected void UpdateRequestState( int aPeerState )
	{
		if( MTConstant.MT_REQ_SSYN_DFLDB_READY == aPeerState ){
			this.mRequestState = MTConstant.MT_REQ_CSYN_DFLDB_SEND_PRODUCT;
		}
		else{
			++curIndex;
			if( curIndex == this.mUpdateItemID.size() - 1 ){
				this.mRequestState = MTConstant.MT_REQ_CSYN_DFLDB_SEND_PRODUCT_LAST;
			}
			else if( curIndex >= this.mUpdateItemID.size() ){
				this.mRequestState = MTConstant.MT_REQ_FINISH;
			}
		}
	}
	
	protected void ProcessReqest( int aPeerState, String peerRawData )
	{
		switch( aPeerState ){
			case MTConstant.MT_REQ_SSYN_DFLDB_UPDATE_PRODUCT:
			case MTConstant.MT_REQ_SSYN_DFLDB_UPDATE_PRODUCT_LAST:{
				
				// Get User ID
				String previousRawData = this.mSendingToPeerRawData.get( curIndex );
				String [] datas = previousRawData.split( "" + MTConstant.MT_REQ_RAW_DATA_SEPARATER );
				
				Cursor updateItem = SQLManager.GetInstance().getReadableDatabase().query(
						SQLManager.TB_UPDATETABLE, 
						null,
						SQLManager.KEY_UPTB_ID + "=?", new String[]{ "" + this.mUpdateItemID.get( this.curIndex) },
						null, null, null );
				updateItem.moveToNext();
				String tempEventID = updateItem.getString( updateItem.getColumnIndex( SQLManager.KEY_UPTB_EVENTID ) );
				String content = updateItem.getString( updateItem.getColumnIndex( SQLManager.KEY_UPTB_CONTENT ) );
				
				int updateType = Integer.valueOf( datas[0] );
				switch( updateType ){
	        		case MTConstant.MT_ID_UPT_EDIT_PRODUCT:{
	        			HandleEditProduct();
	        			break;
	        		}
	        		case MTConstant.MT_ID_UPT_DELETE_PRODUCT:{
	        			HandleDeleteProduct();
	        			break;
	        		}
	        		case MTConstant.MT_ID_UPT_CREATE_PRODUCT:{
	        			HandleCreateProduct( tempEventID, content, peerRawData );
	        			break;
	        		}
	        		case MTConstant.MT_ID_UPT_CREATE_TABLE:{
	        			HandleCreateEventTable( tempEventID, peerRawData );
	        			break;
	        		}
	        		case MTConstant.MT_ID_UPT_DELETE_TABLE:{
	        			HandleDeleteEventTable();
	        			break;
	        		}
	        		case MTConstant.MT_ID_UPT_EDIT_TABLE:{
	        			HandleEditEventTable();
	        			break;
	        		}
				}
				
				// Update Update Table
				String query = String.format(
						"UPDATE UpdateTable SET IsFinished = 1 WHERE ID = %s"
						, this.mUpdateItemID.get( curIndex ) );
				SQLManager.GetInstance().getWritableDatabase().execSQL( query );
				
				//System.out.println("Client ProductID:" + userID );
				this.mReceivedFromPeerRawData.add( peerRawData );
				
				break;
			}
		}
	}
	
	public void SendRequest()
	{
		CheckUpdateProduct();
		
		String request = "" + MTConstant.MT_REQID_SYNCHRONIZE_DATA_FROM_LOCAL_DB + MTConstant.MT_REQ_ITEM_SEPARATER + 
		this.mRequestState + MTConstant.MT_REQ_ITEM_SEPARATER;
		switch( this.mRequestState ){
			case MTConstant.MT_REQ_CSYN_DFLDB_SYNCHRONIZE_REQUEST:{
				String userID = this.mRequestDataSource.GetRawData();
				request += userID;
				break;
			}
			case MTConstant.MT_REQ_CSYN_DFLDB_SEND_PRODUCT:
			case MTConstant.MT_REQ_CSYN_DFLDB_SEND_PRODUCT_LAST:{
				PrepareSendingData();
				request += this.mSendingToPeerRawData.get( curIndex );
				break;
			}
			case MTConstant.MT_REQ_FINISH:{
				this.Finish();
				this.mRequestDataSource.Notify( MTConstant.MT_REQID_SYNCHRONIZE_DATA_FROM_LOCAL_DB , this.mRequestState, "" );
				return;
			}
		}
		this.SendMSG(request);
	}
	
	private void PrepareSendingData()
	{
		SQLManager sqlManager = SQLManager.GetInstance();
		sqlManager.open();
		Cursor updateListInfo = sqlManager.FetchUpdateTableWithID( mUpdateItemID.get( this.curIndex ) );
		
		while( updateListInfo.moveToNext() ){
        	// Check Update Type
        	int updateType = updateListInfo.getInt( updateListInfo.getColumnIndex( SQLManager.KEY_UPTB_UPDATE_TYPE ) );
        	
        	String tempEventID = updateListInfo.getString( updateListInfo.getColumnIndex( SQLManager.KEY_UPTB_EVENTID) );
        	String content = updateListInfo.getString( updateListInfo.getColumnIndex( SQLManager.KEY_UPTB_CONTENT) );
        	String master = updateListInfo.getString( updateListInfo.getColumnIndex( SQLManager.KEY_UPTB_MASTER ) );
        	switch( updateType ){
        		case MTConstant.MT_ID_UPT_EDIT_PRODUCT:{
        			PrepareEditProduct();
        			break;
        		}
        		case MTConstant.MT_ID_UPT_DELETE_PRODUCT:{
        			PrepareDeleteProduct();
        			break;
        		}
        		case MTConstant.MT_ID_UPT_CREATE_PRODUCT:{
        			PrepareCreateProduct( sqlManager, tempEventID, content, master );
        			break;
        		}
        		case MTConstant.MT_ID_UPT_CREATE_TABLE:{
        			PrepareCreateEventTable( sqlManager, tempEventID, content, master );
        			break;
        		}
        		case MTConstant.MT_ID_UPT_DELETE_TABLE:{
        			PrepareDeleteEventTable();
        			break;
        		}
        		case MTConstant.MT_ID_UPT_EDIT_TABLE:{
        			PrepareEditEventTable();
        			break;
        		}
        	}
        }
        updateListInfo.close();
        sqlManager.close();
	}
	
	private void CheckUpdateProduct()
	{
		if( MTConstant.MT_REQ_CSYN_DFLDB_PREPARE_PRODUCT == this.mRequestState ){
			//
			// 1) Search for local Update Table
			//
			
			//
			//  Prepare different type of update type
			
			SQLManager sqlManager = SQLManager.GetInstance();
			sqlManager.open();
			Cursor updateListInfo = sqlManager.FetchUpdateTable();
			
			if( updateListInfo.getCount() > 0 ){
		        while( updateListInfo.moveToNext() ){
		        	for( int j = 0 ; j < updateListInfo.getColumnCount(); ++j ){
		        		System.out.println( "j:" + j +" : " + updateListInfo.getString( j ));
		        	}
		        }
		        updateListInfo.moveToPosition( -1 );
		        while( updateListInfo.moveToNext() ){
		        	// Check Update Type
		        	mUpdateItemID.add( Integer.valueOf( updateListInfo.getInt( updateListInfo.getColumnIndex( SQLManager.KEY_UPTB_ID) )));
		        }
		        updateListInfo.close();
		        sqlManager.close();
				
				// Protocol
				// Update Type ID, EventID, Master, ProductID ( not for Create Product ), Owner, Product Name, Description, Price, Quality, Photo			
				//this.mSendingToPeerRawData.add( this.mRequestDataSource.GetRawData() );
				
				this.mRequestState = MTConstant.MT_REQ_CSYN_DFLDB_SYNCHRONIZE_REQUEST;
			}
			else{
				// No update
				this.mRequestState = MTConstant.MT_REQ_FINISH;
			}
		}
	}
	
	
	//==============================
	//
	// Prepare Raw Data Methods
	//
	//===============================
	
	private void PrepareCreateEventTable( SQLManager sqlManager, String aTempEventID, String aTempProductID, String aMaster )
	{
		Cursor eventItemInfo = sqlManager.FetchEventInfoWithID( aTempEventID );
		eventItemInfo.moveToNext();
		
		// Protocol
		// Update Type, Master , Title, Contact Member, Location
		String rawData = String.format( 
				"" + MTConstant.MT_ID_UPT_CREATE_TABLE + MTConstant.MT_REQ_RAW_DATA_SEPARATER +
				ClientLogic.GetInstance().GetUserID() + MTConstant.MT_REQ_RAW_DATA_SEPARATER +
				"'%s'" + MTConstant.MT_REQ_RAW_DATA_SEPARATER +
				"'%s'" + MTConstant.MT_REQ_RAW_DATA_SEPARATER +
				"'%s'", 
				eventItemInfo.getString( eventItemInfo.getColumnIndex( SQLManager.KEY_EVTTB_TITLE) ),
				eventItemInfo.getString( eventItemInfo.getColumnIndex( SQLManager.KEY_EVTTB_CONTACTMEMBER) ),
				eventItemInfo.getString( eventItemInfo.getColumnIndex( SQLManager.KEY_EVTTB_LOCATION) ) );
		this.mSendingToPeerRawData.add( rawData );
		eventItemInfo.close();
	}
	
	private void PrepareEditEventTable()
	{
		
	}
	
	private void PrepareDeleteEventTable()
	{
		
	}
	
	private void PrepareCreateProduct( SQLManager sqlManager, String aTempEventID, String aTempProductID, String aMaster )
	{
		//mRequestID = MTConstant.MT_REQID_SYNCHRONIZE_DATA_FROM_LOCAL_DB;
		System.out.println("--->PrepareCreateProduct()");
		Cursor productItemInfo = sqlManager.FetchProductItem( 
				aTempEventID,
				aTempProductID );
		
		productItemInfo.moveToFirst();
		
		String eventID = sqlManager.GetExistEventID( aTempEventID );
		System.out.println("aTempEventID:" + aTempEventID);
		System.out.println("eventID:" + eventID);
		// Protocol
		// Update Type ID, EventID, Master, ProductID ( not for Create Product ), Owner, Product Name, Description, Price, Quality, Photo
		this.mSendingToPeerRawData.add(
				"" + MTConstant.MT_ID_UPT_CREATE_PRODUCT + MTConstant.MT_REQ_RAW_DATA_SEPARATER +
				eventID + MTConstant.MT_REQ_RAW_DATA_SEPARATER +
				aMaster + MTConstant.MT_REQ_RAW_DATA_SEPARATER +
				productItemInfo.getString( productItemInfo.getColumnIndex( SQLManager.KEY_PLTB_PRODUCT_NAME) ) + MTConstant.MT_REQ_RAW_DATA_SEPARATER +
				productItemInfo.getString( productItemInfo.getColumnIndex( SQLManager.KEY_PLTB_DESCRIPTION) ) + MTConstant.MT_REQ_RAW_DATA_SEPARATER +
				productItemInfo.getString( productItemInfo.getColumnIndex( SQLManager.KEY_PLTB_PRICE) ) + MTConstant.MT_REQ_RAW_DATA_SEPARATER +
				productItemInfo.getString( productItemInfo.getColumnIndex( SQLManager.KEY_PLTB_QUALITY) ) + MTConstant.MT_REQ_RAW_DATA_SEPARATER +
				productItemInfo.getString( productItemInfo.getColumnIndex( SQLManager.KEY_PLTB_IMAGE) ) );
		productItemInfo.close();
		System.out.println("<---PrepareCreateProduct()");
	}
	
	private void PrepareEditProduct()
	{
		
	}
	
	private void PrepareDeleteProduct()
	{
		
	}
	
	
	//=====================================
	//
	// Handle Different Update Type to update
	//
	//====================================
	
	private void HandleCreateEventTable( String aTempEventID, String aEventID )
	{
		// Update Event ID
		System.out.println( "HandleCreateEventTable()" );
		System.out.println( "aTempEventID: "  + aTempEventID );
		System.out.println( "EventID"  + aEventID );
		SQLManager.GetInstance().open();
		SQLManager.GetInstance().UpdateEventTable(aTempEventID, aEventID);
		SQLManager.GetInstance().close();
		
		// Put All product into Update List
		HandleSynDriftEventProduct( aTempEventID );
	}
	
	private void HandleSynDriftEventProduct(String aTempEventID )
	{
		SQLManager.GetInstance().open();
		Cursor products = SQLManager.GetInstance().FetchProductList(aTempEventID);
		while( products.moveToNext() ){
			String productId = products.getString( products.getColumnIndex( SQLManager.KEY_PLTB_ID ) );
			SQLManager.GetInstance().InsertUpdateTable( aTempEventID, ClientLogic.GetUserID(), productId, MTConstant.MT_ID_UPT_CREATE_PRODUCT );
		}
		SQLManager.GetInstance().close();
	}
	
	
	private void HandleEditEventTable()
	{
		
	}
	
	private void HandleDeleteEventTable()
	{
		
	}
	
	private void HandleCreateProduct( String aTempEventID, String aTempProductID, String aProductID )
	{
		//tempID
		
		
		// Update Product ID
		System.out.println( "HandleCreateProduct()" );
		System.out.println( "ProductID: "  + aProductID );
		System.out.println( "aTempEventID: "  + aTempEventID );
		System.out.println( "aTempProductID: "  + aTempProductID );
		SQLManager.GetInstance().open();
		SQLManager.GetInstance().UpdateProductListTable(aTempEventID, aTempProductID, aProductID);
		SQLManager.GetInstance().close();
	}
	
	private void HandleEditProduct()
	{
		
	}
	
	private void HandleDeleteProduct()
	{
		
	}
	
}